/*
 * Created by IntelliJ IDEA.
 * User: amrk
 * Date: 17/06/2004
 * Time: 00:17:19
 */
package com.talios.jira.idea.intentions;

import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.javadoc.PsiDocToken;
import com.talios.jira.browser.JiraItem;
import com.talios.jira.browser.signals.JiraServerDetails;
import com.talios.jira.idea.JiraConfigurationComponent;
import com.talios.jira.idea.PsiUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @jira INTPLUG-130 Addition of @jira tag confuses input focus
 * @jira INTPLUG-132 Intention to create method broken while 'Working on an issue'
 * @jira INTPLUG-129 infinite additions of @jira tag hung up IDEA
 */
public abstract class AnnotatedIssueCommentIntention implements ProjectComponent, IntentionAction {
    private static final Logger LOGGER = Logger.getInstance("Jira Browser");

    protected String issueKey;

    public static AnnotatedIssueCommentIntention getInstance(Project project) {
        return project.getComponent(JiraIssueBrowseIntention.class);
    }

    public boolean isAvailable(Project project, Editor editor, PsiFile file) {
        int offset = editor.getCaretModel().getOffset();
        PsiElement element = file.findElementAt(offset);
        if (element == null) return false;

        if (element instanceof PsiDocToken || element instanceof PsiComment) {
            if (element instanceof PsiDocToken) {
                element = PsiUtils.findParentPsiElement(element, PsiComment.class);
            }

            final PsiComment comment = (PsiComment) element;

            if (comment.getText().indexOf("@jira") != -1) {
                issueKey = getIssueKeyFromComment(comment.getText());
                return true;
            }
        }

        return false;
    }

    protected String getIssueKeyFromComment(String comment) {
        String issueKey = null;
        comment = comment.replaceAll("\n", " ");
        Matcher matcher = Pattern.compile("(?:.*@jira\\s)([\\w-]*)(?:\\s.*)").matcher(comment);
        if (matcher.matches()) {
            issueKey = matcher.group(1).trim();
        }
        return issueKey;
    }


    protected JiraItem findAnnotatedIssue(Editor editor, PsiFile psiFile, Project project) {
        JiraItem item = null;
        int offset = editor.getCaretModel().getOffset();
        PsiElement element = psiFile.findElementAt(offset);

        if (element instanceof PsiDocToken || element instanceof PsiComment) {
            if (element instanceof PsiDocToken) {
                element = PsiUtils.findParentPsiElement(element, PsiComment.class);
            }

            PsiComment comment = (PsiComment) element;

            String issueKey = getIssueKeyFromComment(comment.getText());

            if (issueKey != null) {
                JiraConfigurationComponent config = project.getComponent(JiraConfigurationComponent.class);

                JiraServerDetails server = config.findServerForIssueKey(issueKey);
                if (server != null) {
                    item = server.findIssue(issueKey);
                }
            }
        }
        return item;
    }
}